/**
 * @author cqb 2016-04-05.
 * @module Button
 */

import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import Emitter from '../utils/Emitter';
import Icon from '../Icon';
import './Button.less';


/**
 * Button 类
 * @class Button
 * @constructor
 * @extends BaseComponent
 */
class Button extends React.PureComponent {
    static displayName = 'Button';

    static propTypes = {
        /**
         * 自定义class
         * @attribute className
         * @type {String}
         */
        className: PropTypes.string,
        /**
         * 自定义样式
         * @attribute style
         * @type {Object}
         */
        style: PropTypes.object,
        /**
         * 禁用
         * @attribute disabled
         * @type {Boolean}
         */
        disabled: PropTypes.bool,
        /**
         * 主题
         * @attribute theme
         * @type {String}
         */
        theme: PropTypes.string,
        bind: PropTypes.func,
        unBind: PropTypes.func,
        /**
         * 无边框效果
         * @attribute flat
         * @type {string/bool}
         */
        flat: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
        /**
         * 链接地址
         * @attribute href
         * @type {string}
         */
        href: PropTypes.string,
        /**
         * 图标
         * @attribute icon
         * @type {string}
         */
        icon: PropTypes.any,
        /**
         * 图标位置
         * @attribute iconAlign
         * @type {string}
         */
        iconAlign: PropTypes.oneOf(['left', 'right']),
        /**
         * 按钮尺寸
         * @attribute size
         * @type {string}
         */
        size: PropTypes.oneOf(['default', 'large', 'small']),
        /**
         * 跳转的目标通a标签的target
         * @attribute target
         * @type {string}
         */
        target: PropTypes.string,
        /**
         * 图片
         * @attribute img
         * @type {string}
         */
        img: PropTypes.string
    }

    static defaultProps = {
        theme: 'default',
        disabled: false,
        iconAlign: 'left',
        img: null,
        size: null,
        raised: false,
        flat: false,
        circle: false,
        active: false,
        animation: true,
        loading: false
    }

    lastClick = null;

    /**
     * 点击回调
     * @private
     * @method handleClick
     */
    handleClick = e => {
        if (this.props.disabled) {
            return;
        }
        if (this.props.loading) {
            return;
        }
        // 先执行一次click，快速点击执行doubleClick，永远不会触发连续两次的单击
        const time = new Date().getTime();
        if (!this.lastClick) {
            if (this.props.onClick) {
                this.props.onClick(e);
            }
            this.emit('click', e);
        } else {
            const diff = time - this.lastClick;
            if (diff < 300) {
                if (this.props.onDoubleClick) {
                    this.props.onDoubleClick(e);
                }
                this.lastClick = null;
                return;
            } else {
                if (this.props.onClick) {
                    this.props.onClick(e);
                }
                this.emit('click', e);
            }
        }
        this.lastClick = time;
    }

    componentDidMount () {
        this._isMounted = true;
        if (this.props['bind']) {
            this.props['bind'](this);
        }
    }

    componentWillUnmount () {
        if (this.props['unBind']) {
            this.props['unBind'](this);
        }
    }

    getLoading () {
        const {size} = this.props;
        let iconSize = 14;
        if (size === 'small') {
            iconSize = 12;
        }
        return <span style={{width: iconSize, height: iconSize}} className='cm-button-loading'>
            <svg xmlns='http://www.w3.org/2000/svg' width={iconSize} height={iconSize} viewBox='0 0 38 38' stroke='#fff'>
                <g fill='none' fillRule='evenodd'>
                    <g transform='translate(1 1)' strokeWidth='2'>
                        <circle strokeOpacity='.5' cx='18' cy='18' r='18'/>
                        <path d='M36 18c0-9.94-8.06-18-18-18' transform='rotate(113.635 18 18)'>
                            <animateTransform attributeName='transform' type='rotate' from='0 18 18' to='360 18 18' dur='1s' repeatCount='indefinite'/>
                        </path>
                    </g>
                </g>
            </svg>
        </span>;
    }

    /**
     * 渲染
     */
    render () {
        let {id, className, style, target, size, iconButton, circle, active,
            iconAlign, icon, href, children, img, title, loading} = this.props;
        className = classNames(
            className,
            'cm-button',
            this.props.theme,
            {
                [`cm-button-${size}`]: size,
                'cm-iconButton': iconButton,
                'cm-button-active': active,
                'cm-button-circle': circle,
                'cm-button-icon-only': !!icon && !children
            }
        );

        const link = href || null;

        const iconPosition = iconAlign || 'left';
        let fontIcon = null;
        if (icon) {
            const iconStyle = iconPosition === 'left' ? {marginRight: children ? 5 : 0} : {marginLeft: children ? 5 : 0};
            fontIcon = typeof icon === 'string' ? <Icon name={icon} className={iconPosition} style={iconStyle} /> : icon;
        }

        if (img) {
            img = <img src={img} className='cm-button-img' alt='' style={{marginRight: children ? 5 : 0}} />;
        }

        const nodes = iconPosition === 'left'
            ? (<span>
                {img}
                {fontIcon}
                {children}
            </span>)
            : (<span>
                {img}
                {children}
                {fontIcon}
            </span>);
        if (link) {
            return <a ref={(f) => this.button = f}
                id={id}
                href={link}
                disabled={this.props.disabled}
                onClick={this.handleClick}
                className={className}
                style={style}
                target={target}
                title={title}>
                {loading ? this.getLoading() : null}
                {nodes}
            </a>;
        }
        return (
            <button ref={(f) => this.button = f}
                id={id}
                disabled={this.props.disabled}
                onClick={this.handleClick}
                className={className}
                style={style}
                title={title}>
                {loading ? this.getLoading() : null}
                {nodes}
            </button>
        );
    }
}

Emitter.inherits(Button);

export default Button;
